﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Utils.Wpf
{
	public class ControlRenderer
	{
		#region Attributes

		private readonly int _dpiX;
		private readonly int _dpiY;

		#endregion

		#region Public Methods

		public ControlRenderer(int dpiX, int dpiY)
		{
			_dpiX = dpiX;
			_dpiY = dpiY;
		}

		public BitmapSource Render(FrameworkElement control)
		{
			if (control == null)
			{
				throw new ArgumentNullException("control");
			}

			RenderTargetBitmap result;

			if (control is Image)
			{
				result = (RenderTargetBitmap)((Image)control).Source;
			}
			else
			{
				Viewbox viewBox = new Viewbox();
				viewBox.Child = control; // Control to render
				viewBox.Measure(new System.Windows.Size(control.Width, control.Height));
				viewBox.Arrange(new Rect(0, 0, control.Width, control.Height));

				result = new RenderTargetBitmap((int)(control.Width * _dpiX / 96.0), (int)(control.Height * _dpiY / 96.0), _dpiX, _dpiY, PixelFormats.Pbgra32);

				DrawingVisual drawingVisual = new DrawingVisual();
				using (DrawingContext drawingContext = drawingVisual.RenderOpen())
				{
					VisualBrush visualBrush = new VisualBrush(viewBox);
					drawingContext.DrawRectangle(visualBrush, null, new Rect(new Point(), new System.Windows.Size(control.Width, control.Height)));
				}

				result.Render(drawingVisual);
				result.Freeze();

				// Remove the container to be able to reuse the control again if we appended it to a viewbox
				viewBox.Child = null;
			}

			return result;
		}

		#endregion
	}
}
